package com.mall.gateway.filter;

import com.alibaba.fastjson.JSON;
import com.mall.gateway.permission.AuthorizationInterceptor;
import com.mall.gateway.queue.HotQueue;
import com.mall.gateway.util.IPUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Darren
 * @date 2022-10-17 15:27
 * Description：
 */
@Configuration
public class RequestFilter implements GlobalFilter, Ordered {
    @Autowired
    private HotQueue hotQueue;
    @Autowired
    private AuthorizationInterceptor authorizationInterceptor;

    /**
     * 拦截所有请求
     *
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        // 获取uri
        String uri = request.getURI().getPath();

        // 路径是否有效
        if (!authorizationInterceptor.isInvalid(uri)) {
            endProcess(exchange, 404, "url not find");
            return chain.filter(exchange);
        }

        // 是否需要拦截
        if (!authorizationInterceptor.isIntercept(exchange)) {
            // 无需拦截,放行
            return chain.filter(exchange);
        }

        // 令牌校验
        Map<String, Object> jwtVerifyMap = tokenIntercept(exchange);
        if (jwtVerifyMap == null) {
            endProcess(exchange, 401, "token error");
            return chain.filter(exchange);
        }

        // 权限校验
        if (!authorizationInterceptor.rolePermissionVerify(exchange, jwtVerifyMap)) {
            // 权限不足
            endProcess(exchange, 401, "Insufficient permissions");
            return chain.filter(exchange);
        }

        // NOT_HOT 直接由后端服务器处理
        return chain.filter(exchange);
    }

    /**
     * 令牌校验
     *
     * @param exchange
     * @return
     */
    private Map<String, Object> tokenIntercept(ServerWebExchange exchange) {
        ServerHttpRequest request = exchange.getRequest();
        // 客户端ip
        String clientIp = IPUtils.getIp(request);
        // 获取token
        String token = request.getHeaders().getFirst("authorization");
        // 令牌检验
        return AuthorizationInterceptor.jwtVerify(token, clientIp);
    }

    /**
     * 秒杀过滤
     *
     * @param exchange
     * @param request
     */
    private void seckillFilter(ServerWebExchange exchange, ServerHttpRequest request, String username) {
        // 商品id
        String id = request.getQueryParams().getFirst("id");
        // 数量
        Integer num = Integer.valueOf(request.getQueryParams().getFirst("num"));
        // 排队结果
        int result = hotQueue.hotToQueue(username, id, num);
        if (HotQueue.QUEUE_ING.equals(result) || HotQueue.HAS_QUEUE.equals(result)) {
            endProcess(exchange, result, "hot");
        }
    }

    /**
     * 结束过滤,返回信息
     *
     * @param exchange
     * @param result
     */
    private void endProcess(ServerWebExchange exchange, Integer code, String message) {
        Map<String, Object> resultMap = new HashMap<>(2);
        resultMap.put("code", code);
        resultMap.put("message", message);
        exchange.getResponse().setStatusCode(HttpStatus.OK);
        exchange.getResponse().setComplete();
        exchange.getResponse().getHeaders().add("message", JSON.toJSONString(resultMap));
    }

    @Override
    public int getOrder() {
        return 10001;
    }
}
